﻿using SelfManagement.Database.POCO;
using Ninject;
using SelfManagement.IServices;
using SelfManagement.Utility.Helper;
using SelfManagement.Mvc.Result;
using SelfManagement.Mvc.Helper;
using MvcPaging;
using SelfManagement.Web.Infrastructure;
using System.Web.Mvc;
using SelfManagement.Web.Models.ViewModels.ArticleModels;
using SelfManagement.Utility.Extensions;
using System.Linq;
using SelfManagement.Mvc.Models;
using System.Collections.Generic;

namespace SelfManagement.Web.Controllers
{
    [UserAuthorize]
    public class ArticleController : CommonBaseController
    {
        [Inject]
        public IArticleCategoryService ArticleCategoryService { get; set; }
        [Inject]
        public IArticleService ArticleService { get; set; }

        /// <summary>
        /// 文章主页
        /// </summary>
        /// <param name="viewModel"></param>
        /// <returns></returns>
        public ActionResult Index(ArticlePagedListViewModel viewModel)
        {
            IQueryable<Article> query = ArticleService.QueryUserArticles(UserSession.Identity);
            string key = viewModel.Keyword;
            viewModel.Categories = ArticleCategoryService.GetUserArticleCategories(UserSession.Identity);
            viewModel.Category = viewModel.Categories.FirstOrDefault(c => c.Id == viewModel.Category_Id);

            if (viewModel.Category.IsNotNull())
            {
                query = query.Where(a => a.Category_Id == viewModel.Category_Id);
            }
            else
            {
                viewModel.Category_Id = null;
            }
            if (key.IsNotNullAndNotWhiteSpace())
            {
                query = query.Where(a => a.Title.Contains(key));
            }

            viewModel.PagedList = query.OrderByDescending(a => a.IsTop)
                                       .ThenByDescending(a => a.CreatedTime)
                                       .ToPagedList(viewModel.PageIndex, viewModel.Size);
            viewModel.QueryParameter = GetParameterFromQueryString();
            SetPageTitle("文章管理");
            return View(viewModel);
        }

        /// <summary>
        /// 保存文章分类顺序
        /// </summary>
        /// <param name="orderInfo"></param>
        /// <returns></returns>
        public ActionResult SaveCategoriesOrder(string orderInfo)
        {
            var result = new JsonResultData();
            result.RunWithTry(data =>
            {
                var nestableNodes =
                     orderInfo.ToObject<List<NestableNote>>(JsonExtensions.PropertyNaming.CamelCase);

                List<ArticleCategory> categories = new List<ArticleCategory>();
                List<ArticleCategory> allCategories = ArticleCategoryService.GetUserArticleCategories(UserSession.Identity);

                if (nestableNodes.IsNotEmpty())
                {
                    int order = 1;
                    foreach (var nNode in nestableNodes)
                    {
                        var tempCategory = allCategories.FirstOrDefault(p => p.Id == nNode.id);
                        if (tempCategory.IsNotNull())
                        {
                            tempCategory.Order = order++;
                        }
                        ArticleCategoryService.Update(tempCategory);
                        categories.Add(tempCategory);
                    }
                }
                
                categories.ForEach(p => ArticleCategoryService.Update(p));
                data.Success = true;
                data.ReloadPage = true;
                data.AddMessage("保存成功！");
            });
            return JsonAllowGet(result);
        }

        /// <summary>
        /// 新增或编辑分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult CreateOrEditCategory(string id)
        {
            bool isEdit = id.IsNotNullAndNotWhiteSpace();
            string uid = UserSession.Identity;

            ArticleCategory articleCategory = isEdit ? ArticleCategoryService.GetUserArticleCategoryById(uid, id)
                                                     : new ArticleCategory();
            if (articleCategory.IsNull())
            {
                return RedirectToError("找不到这篇文章", code: 404);
            }
            CategoryViewModel viewModel = new CategoryViewModel();
            if (isEdit)
            {
                ValueCopyHelper.CopyProperty(viewModel, articleCategory, false, nameof(viewModel.CategoryName));
            }

            viewModel.IsEdit = isEdit;
            string title = (isEdit ? "编辑" : "新增") + "文章分类";
            SetPageTitle(title);
            SetBreadcrumb(title, "文章管理", Url.Action("Index"));
            return View(viewModel);
        }

        /// <summary>
        /// 新增或编辑分类
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateOrEditCategory(CategoryViewModel post)
        {
            JsonResultData result = new JsonResultData();
            result.RunWithTry(data =>
            {
                if (ModelState.IsValid)
                {
                    string uid = UserSession.Identity;
                    ArticleCategory articleCategory = post.IsEdit ? ArticleCategoryService.GetUserArticleCategoryById(uid, post.Id)
                                                                  : new ArticleCategory();
                    ValueCopyHelper.CopyProperty(articleCategory, post, false, nameof(post.CategoryName));
                    articleCategory.User_Id = UserSession.Identity;
                    if (ArticleCategoryService.IsExistsUserCategoryByName(articleCategory))
                    {
                        result.AddMessage($"文章分类【{articleCategory.CategoryName}】已存在");
                        return;
                    }
                    if (post.IsEdit)
                    {
                        articleCategory.SetUpdateInfo(UserSession.UserEntity.UserName);
                        ArticleCategoryService.Update(articleCategory);
                    }
                    else
                    {
                        articleCategory.SetCreateAndUpdateInfo(UserSession.UserEntity.UserName);
                        ArticleCategoryService.Insert(articleCategory);
                    }
                    result.AddMessage("保存成功！");
                    result.Success = true;
                    result.RedirectUrl = Url.Action("Index");
                }
                else
                {
                    result.AddModelValidErrorMessage(ModelState);
                }
            });
            return Json(result);
        }

        /// <summary>
        /// 删除文章分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult DeleteCategory(string id)
        {
            JsonResultData result = new JsonResultData();
            result.RunWithTry(t =>
            {
                result.Success = ArticleCategoryService.DeleteUserCategoryById(UserSession.Identity, id);
                result.AddMessage("删除" + (result.Success ? "成功" : "失败"));
                if (result.Success)
                {
                    result.RedirectUrl = Url.Action("Index");
                }
            });
            return JsonAllowGet(result);
        }

        /// <summary>
        /// 新增或者修改文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult CreateOrEdit(string id, string categoryId=null)
        {
            bool isEdit = id.IsNotNullAndNotWhiteSpace();
            string uid = UserSession.Identity;

            Article article = isEdit ? ArticleService.GetUserArticleById(uid, id)
                                     : new Article()
                                     {
                                         Category_Id = categoryId
                                     };
            if (article.IsNull())
            {
                return RedirectToError("找不到这篇文章", code: 404);
            }
            ArticleViewModel viewModel = new ArticleViewModel();
            if (isEdit)
            {
                ArticleModelTransform(article, viewModel);
            }
            viewModel.SelectCategories = ArticleCategoryService.QueryUserArticleCategories(UserSession.Identity)
                                                     .OrderBy(c => c.Order)
                                                     .ThenByDescending(c => c.CreatedTime)
                                                     .Select(c => new SelectListItem()
                                                     {
                                                         Text = c.CategoryName,
                                                         Value = c.Id,
                                                         Selected = c.Id == article.Category_Id
                                                     }).ToList();
            viewModel.IsEdit = isEdit;
            string title = (isEdit ? "编辑" : "新增") + "文章";
            SetPageTitle(title);
            SetBreadcrumb(title, "文章管理", Url.Action("Index"));
            return View(viewModel);
        }

        public ActionResult Detail(string id)
        {
            Article article = ArticleService.GetUserArticleById(UserSession.Identity, id);
            if (article.IsNull())
            {
                return RedirectToError("找不到这篇文章", code: 404);
            }
            SetPageTitle(article.Title);
            SetBreadcrumb("文章详情", "文章管理", Url.Action("Index"));
            return View(article);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        public ActionResult CreateOrEdit(ArticleViewModel post)
        {
            JsonResultData result = new JsonResultData();
            result.RunWithTry(data =>
            {
                if (ModelState.IsValid)
                {
                    string uid = UserSession.Identity;
                    Article article = post.IsEdit ? ArticleService.GetUserArticleById(uid, post.Id)
                                                                  : new Article();
                    ArticleModelTransform(article, post, false);
                    if (post.IsEdit)
                    {
                        article.SetUpdateInfo(UserSession.UserEntity.UserName);
                        ArticleService.Update(article);
                    }
                    else
                    {
                        article.User_Id = UserSession.Identity;
                        article.SetCreateAndUpdateInfo(UserSession.UserEntity.UserName);
                        ArticleService.Insert(article);
                    }
                    result.AddMessage("保存成功！");
                    result.Success = true;
                    result.RedirectUrl = Url.Action("Index");
                }
                else
                {
                    result.AddModelValidErrorMessage(ModelState);
                }
            });
            return Json(result);
        }

        /// <summary>
        /// 删除文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Delete(string id)
        {
            JsonResultData result = new JsonResultData();
            result.RunWithTry(t =>
            {
                result.Success = ArticleService.DeleteUserArticleById(UserSession.Identity, id);
                result.AddMessage("删除" + (result.Success ? "成功" : "失败"));
                result.ReloadPage = result.Success;
            });
            return JsonAllowGet(result);
        }

        private void ArticleModelTransform(Article article, ArticleViewModel model, bool isView = true)
        {
            if (isView)
            {
                ValueCopyHelper.CopyProperty(model, article, false,
                                                nameof(article.Title),
                                                nameof(article.Content),
                                                nameof(article.Category_Id),
                                                nameof(article.ViewPermission),
                                                nameof(article.IsTop));
            }
            else
            {
                ValueCopyHelper.CopyProperty(article, model, false,
                                                nameof(model.Title),
                                                nameof(model.Content),
                                                nameof(model.Category_Id),
                                                nameof(model.IsTop));
            }
        }
    }
}